package com.swak.validator.process.impl;

import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import com.swak.Constants;
import com.swak.annotation.validate.Range;
import com.swak.utils.Converters;
import com.swak.utils.Maps;
import com.swak.utils.StringUtils;
import com.swak.validator.process.AbstractProcessor;

/**
 * 范围值处理
 *
 * @author lifeng
 */
public class RangeProcessor extends AbstractProcessor {

	private Map<Range, Set<Object>> values = Maps.newHashMap();

	/**
	 * 处理的类型
	 */
	@Override
	protected Class<?> processBy() {
		return Range.class;
	}

	/**
	 * 为 null 判断
	 */
	@Override
	protected boolean doProcess(Annotation check, Object value, String group) {
		Range max = (Range) check;
		if (!this.matchGroup(max.groups(), group)) {
			return true;
		}

		if (value != null) {
			Set<Object> vs = this.values.get(max);
			if (vs == null && max.values() != null && max.values().length > 0) {
				vs = this.processValues(max, value);
			} 
			return vs == null ? false : vs.contains(value);
		}
		return true;
	}

	protected Set<Object> processValues(Range max, Object value) {
		Set<Object> vs = Arrays.stream(max.values()).map(v -> Converters.doConvert(v, value.getClass()))
				.collect(Collectors.toSet());
		this.values.put(max, vs);
		return vs;
	}

	/**
	 * 处理为空的异常消息
	 */
	@Override
	protected String processMessage(Annotation check) {
		Range max = (Range) check;
		return StringUtils.defaultIfEmpty(max.msg(), Constants.RANGE_ERROR_MSG);
	}
}